from rest_framework import serializers
from django.db import transaction
from apps.goods.models import SKU,SKUSpecification
from celery_tasks.detail.tasks import generate_task

class SpecsRelatedSerializer(serializers.Serializer):
    #发生一些警告Column 'spec_id' cannot be null")   原因：无法找到spec_id的数据  应该是类型找不到
    spec_id = serializers.IntegerField()
    option_id = serializers.IntegerField()

class SkuModelSerializer(serializers.ModelSerializer):
    #spu标准商品
    spu = serializers.StringRelatedField(read_only=True)
    spu_id = serializers.IntegerField()
    #三级分类
    category = serializers.StringRelatedField(read_only=True)
    category_id = serializers.IntegerField()

    #规格信息  sku商品库存表连接商品的规格表信息
    specs = SpecsRelatedSerializer(many=True)
    class Meta:
        model = SKU
        fields = "__all__"

#ViewSet里面存在的增删改查等操作 增的部分中涉及规格按钮的操作
# 有的SPU的按钮的规格是两个规格  有的SPU是三个规格按钮  故 增加时为了方便省事 直接先删除SPU对应的规格按钮，然后在创建新的规格
#故重写create方法
    def create(self,validated_data):
        #删除specs的规格部分,同时取出specs
        specs = validated_data.pop('specs')
        '''
        "specs": [{"spec_id": 6,"option_id": 16},
                 {"spec_id": 7,"option_id": 21}]
        '''
        #创建SKU对象   通过对于父类的继承然后使用父类的create发放进行sku对象的创建
        #同时 sku 的创建为
#添加事务 同时操作两张表单数据  不能出现一张存在数据一张不存在数据
        with transaction.atomic():
            sid = transaction.savepoint()
            try:
                sku = super().create(validated_data)

                #创建sku规格的对象  遍历
                for item in specs:
                    #sku规格对象需要指定  sku_id specs_id option_id
                    item['sku_id'] = sku.id
                    #创建sku规格对象  通过sku_id specs_id option_id得到唯一确定的sku规格商品
                    SKUSpecification.objects.create(**item)
            except:
                transaction.savepoint_rollback(sid)  #事务回滚
                raise serializers.ValidationError("创建sku失败")
            else:
                transaction.savepoint_commit(sid)  #事务提交

                #生成静态文件
                generate_task.delay(sku.id)
                return sku
    #修改数据   'N
    def update(self,instance,validated_data):
        # 删除specs的规格部分,同时取出specs

        specs = validated_data.pop('specs')
        with transaction.atomic():
            sid = transaction.savepoint()
            try:
                #继承父类的方法  进行实例的修改
                instance = super().update(instance,validated_data)
                #修改规格及其选项   删除所有的规格  直接进行删除然后进行规格的创建
                SKUSpecification.objects.filter(sku_id = instance.id).delete()

                #遍历 直接创建规格
                for item in specs:
                    item['sku_id'] = instance.id
                    SKUSpecification.objects.create(**item)
            except:
                transaction.savepoint_rollback(sid)
                raise serializers.ValidationError("修改sku失败")
            else:
                transaction.savepoint_commit(sid)

                #采用celery异步修改静态文件
                generate_task.delay(instance.id)
        return instance

#在添加图片管理里面的新增商品图片的位置  简单地查询sku商品
class SkuSimpleSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField()  ##非关系属性使用这个
